#include <base.h>
#include <ctype.h>
#include <jansson.h>

// 读取JSON文件内容
char *get_opcodes_json() {
    FILE *fp = fopen("opcodes/Opcodes.txt", "r");
    if (fp == NULL) {
        perror("Error opening file");
        return NULL;
    }

    // 获取文件大小
    fseek(fp, 0, SEEK_END);
    long file_size = ftell(fp);
    fseek(fp, 0, SEEK_SET);

    // 分配内存
    char *buffer = (char *)malloc(file_size + 1);
    if (buffer == NULL) {
        perror("Memory allocation failed");
        fclose(fp);
        return NULL;
    }

    // 读取文件内容
    size_t read_size = fread(buffer, 1, file_size, fp);
    buffer[read_size] = '\0';

    fclose(fp);
    return buffer;
}

// 解析JSON数据并获取指定操作码的信息
json_t *get_opcode_info(uint8_t opcode, bool is_cb_prefixed) {
    char *json_str = get_opcodes_json();
    if (json_str == NULL) {
        return NULL;
    }

    json_error_t error;
    json_t *root = json_loads(json_str, 0, &error);
    free(json_str);

    if (!root) {
        fprintf(stderr, "JSON error: %s\n", error.text);
        return NULL;
    }

    // 根据是否有CB前缀选择不同的操作码集
    const char *prefix = is_cb_prefixed ? "cbprefixed" : "unprefixed";
    json_t *opcodes = json_object_get(root, prefix);
    if (!opcodes) {
        json_decref(root);
        return NULL;
    }

    // 构造操作码的十六进制字符串
    char opcode_hex[5];
    snprintf(opcode_hex, sizeof(opcode_hex), "0x%02X", opcode);

    // 获取指定操作码的信息
    json_t *opcode_info = json_object_get(opcodes, opcode_hex);
    if (!opcode_info) {
        json_decref(root);
        return NULL;
    }

    // 增加引用计数，防止root被释放时opcode_info也被释放
    json_incref(opcode_info);
    json_decref(root);

    return opcode_info;
}

// 获取指令的助记符
char *get_mnemonic(uint8_t opcode, bool is_cb_prefixed) {
    json_t *opcode_info = get_opcode_info(opcode, is_cb_prefixed);
    if (!opcode_info) {
        return NULL;
    }

    json_t *mnemonic_json = json_object_get(opcode_info, "mnemonic");
    if (!mnemonic_json) {
        json_decref(opcode_info);
        return NULL;
    }

    const char *mnemonic = json_string_value(mnemonic_json);
    char *result = strdup(mnemonic);
    
    json_decref(opcode_info);
    return result;
}

// 获取指令的字节数
int get_bytes(uint8_t opcode, bool is_cb_prefixed) {
    json_t *opcode_info = get_opcode_info(opcode, is_cb_prefixed);
    if (!opcode_info) {
        return -1;
    }

    json_t *bytes_json = json_object_get(opcode_info, "bytes");
    if (!bytes_json) {
        json_decref(opcode_info);
        return -1;
    }

    int bytes = json_integer_value(bytes_json);
    
    json_decref(opcode_info);
    return bytes;
}

// 获取指令的周期数
struct Cycles *get_cycles(uint8_t opcode, bool is_cb_prefixed) {
    json_t *opcode_info = get_opcode_info(opcode, is_cb_prefixed);
    if (!opcode_info) {
        return NULL;
    }

    json_t *cycles_json = json_object_get(opcode_info, "cycles");
    if (!cycles_json || !json_is_array(cycles_json)) {
        json_decref(opcode_info);
        return NULL;
    }

    struct Cycles *head = NULL;
    struct Cycles *current = NULL;
    
    size_t index;
    json_t *value;
    
    json_array_foreach(cycles_json, index, value) {
        struct Cycles *cycle = (struct Cycles *)malloc(sizeof(struct Cycles));
        if (!cycle) {
            // 内存分配失败，释放已分配的内存
            while (head) {
                current = head;
                head = head->next;
                free(current);
            }
            json_decref(opcode_info);
            return NULL;
        }
        
        cycle->t = json_integer_value(value);
        cycle->next = NULL;
        
        if (!head) {
            head = cycle;
            current = cycle;
        } else {
            current->next = cycle;
            current = cycle;
        }
    }
    
    json_decref(opcode_info);
    return head;
}

// 获取指令的操作数
struct Operand *get_operands(uint8_t opcode, bool is_cb_prefixed) {
    json_t *opcode_info = get_opcode_info(opcode, is_cb_prefixed);
    if (!opcode_info) {
        return NULL;
    }

    json_t *operands_json = json_object_get(opcode_info, "operands");
    if (!operands_json || !json_is_array(operands_json)) {
        json_decref(opcode_info);
        return NULL;
    }

    struct Operand *head = NULL;
    struct Operand *current = NULL;
    
    size_t index;
    json_t *value;
    
    json_array_foreach(operands_json, index, value) {
        struct Operand *operand = (struct Operand *)malloc(sizeof(struct Operand));
        if (!operand) {
            // 内存分配失败，释放已分配的内存
            while (head) {
                current = head;
                head = head->next;
                free(current->name);
                free(current);
            }
            json_decref(opcode_info);
            return NULL;
        }
        
        json_t *name_json = json_object_get(value, "name");
        json_t *bytes_json = json_object_get(value, "bytes");
        json_t *immediate_json = json_object_get(value, "immediate");
        json_t *increment_json = json_object_get(value, "increment");
        json_t *decrement_json = json_object_get(value, "decrement");
        
        if (name_json && json_is_string(name_json)) {
            operand->name = strdup(json_string_value(name_json));
        } else {
            operand->name = strdup("");
        }
        
        operand->bytes = bytes_json ? json_integer_value(bytes_json) : 0;
        operand->immediate = immediate_json ? json_is_true(immediate_json) : false;
        operand->increment = increment_json ? json_is_true(increment_json) : false;
        operand->decrement = decrement_json ? json_is_true(decrement_json) : false;
        operand->next = NULL;
        
        if (!head) {
            head = operand;
            current = operand;
        } else {
            current->next = operand;
            current = operand;
        }
    }
    
    json_decref(opcode_info);
    return head;
}

// 获取指令是否为立即数
bool get_immediate(uint8_t opcode, bool is_cb_prefixed) {
    json_t *opcode_info = get_opcode_info(opcode, is_cb_prefixed);
    if (!opcode_info) {
        return false;
    }

    json_t *immediate_json = json_object_get(opcode_info, "immediate");
    bool immediate = immediate_json ? json_is_true(immediate_json) : false;
    
    json_decref(opcode_info);
    return immediate;
}

// 获取指令对标志位的影响
struct Flags *get_flags(uint8_t opcode, bool is_cb_prefixed) {
    json_t *opcode_info = get_opcode_info(opcode, is_cb_prefixed);
    if (!opcode_info) {
        return NULL;
    }

    json_t *flags_json = json_object_get(opcode_info, "flags");
    if (!flags_json || !json_is_object(flags_json)) {
        json_decref(opcode_info);
        return NULL;
    }

    struct Flags *flags = (struct Flags *)malloc(sizeof(struct Flags));
    if (!flags) {
        json_decref(opcode_info);
        return NULL;
    }
    
    json_t *z_json = json_object_get(flags_json, "Z");
    json_t *n_json = json_object_get(flags_json, "N");
    json_t *h_json = json_object_get(flags_json, "H");
    json_t *c_json = json_object_get(flags_json, "C");
    
    flags->Z = z_json && json_is_string(z_json) ? strdup(json_string_value(z_json)) : strdup("-");
    flags->N = n_json && json_is_string(n_json) ? strdup(json_string_value(n_json)) : strdup("-");
    flags->H = h_json && json_is_string(h_json) ? strdup(json_string_value(h_json)) : strdup("-");
    flags->C = c_json && json_is_string(c_json) ? strdup(json_string_value(c_json)) : strdup("-");
    
    json_decref(opcode_info);
    return flags;
}